#include "PbConvertor.h"
#include "test.pb.h"
#include "test.h"
#include <fstream>
#include <iostream>
// #include "Cdd_IpcfShm_Platform.pb.h"
#include "Cdd_IpcfShm_Platform_c.pb.h"
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>

#define SOCKET_PATH "/tmp/unix_dgram_socket"

#if 0
void test_demo()
{
    // testBox testMessage;

    // testData testChildMessage;
    // testChildMessage.b = 1;
    // testChildMessage.c = 2;
    // testChildMessage.d = 3;
    // int32_t array[4] = {1,2,3,4};
    // testChildMessage.e = array;

    // testMessage.data = testChildMessage;

    testNamespace::TestMessage testMessage;

    testMessage.doubleField = 1.234;
    // testMessage.floatField = 1.23;
    testMessage.int32Field = -123;
    testMessage.int64Field = -1234;
    testMessage.uint32Field = 123;
    // testMessage.uint64Field = 1234;
    testMessage.boolField = true;
    testMessage.stringField = "Hello, 科比.布莱恩特.";
    testMessage.testEnumField = testNamespace::enum3;

    double arr1[3] = {1.234, 5.678, 9.101112};
    testMessage.repeatedDoubleField = arr1;
    testMessage.repeatedStringLengthField = 3;

    char *pSerializedPb;
    size_t serializedPbSize;
    if (PbConvertor::struct2serializedPb((const char *)&testMessage, "testPackage.TestMessage", pSerializedPb, serializedPbSize))
    {
        testPackage::TestMessage testMessagePb;
        // box testMessagePb;
        bool bRet = testMessagePb.ParseFromArray(pSerializedPb, serializedPbSize);

        std::fstream ofs("test.pb.txt", std::ios::out | std::ios::trunc);
        
        if(ofs.is_open()) {
            testMessagePb.SerializeToOstream(&ofs);
        }
        ofs.close();
        // printf("b:%d, c:%d, d:%lf, e:%d\n", testMessagePb.data().b(), testMessagePb.data().c(), testMessagePb.data().d(), testMessagePb.data().e(2));
        printf("b:%lf, c:%lf, d:%lf\n", testMessagePb.repeateddoublefield(0), testMessagePb.repeateddoublefield(1), testMessagePb.repeateddoublefield(2));

        PbConvertor::MemTree stru;
        if (PbConvertor::serializedPb2struct("testPackage.TestMessage", pSerializedPb, serializedPbSize, stru))
        {
            testNamespace::TestMessage *pTestMessage = (testNamespace::TestMessage *)stru.pMem;
            // printf("b:%d, c:%d, d:%lf, e:%d\n", pTestMessage->data.b, pTestMessage->data.c, pTestMessage->data.d, pTestMessage->data.e[2]);
            printf("b:%lf, c:%lf, d:%lf\n", testMessagePb.repeateddoublefield(0), testMessagePb.repeateddoublefield(1), testMessagePb.repeateddoublefield(2));
            stru.release();
        }
        delete [] pSerializedPb;
    }
}

#endif

void test_VDU()
{
    _Cdd_IpcfShm_Cdd_IpcfPbMsg_Data_Acquire_M2A struc_obj;
    struc_obj.IpcfChanl_Header.Mesg_ID = 0x12;
    struc_obj.IpcfChanl_Header.Timestamp_Sec = 123123;
    struc_obj.Main_Battery_Info_Data.bytes[1] = 1;
    struc_obj.Main_Battery_Info_Data.bytes[479] = 479;

    // char *pSerializedPb;
    // size_t serializedPbSize;
    // if (PbConvertor::struct2serializedPb((const char *)&struc_obj, "Cdd_IpcfShm.Cdd_IpcfPbMsg_Data_Acquire_M2A", pSerializedPb, serializedPbSize))
    // {
        // Cdd_IpcfShm::Cdd_IpcfPbMsg_Data_Acquire_M2A testMessagePb;
        // // box testMessagePb;
        // bool bRet = testMessagePb.ParseFromArray(pSerializedPb, serializedPbSize);

        // std::fstream ofs("vduproto.pb.txt", std::ios::out | std::ios::trunc);
        // if(ofs.is_open()) {
        //     testMessagePb.SerializeToOstream(&ofs);
        // }
        // ofs.close();
        // // printf("b:%d, c:%d, d:%lf, e:%d\n", testMessagePb.data().b(), testMessagePb.data().c(), testMessagePb.data().d(), testMessagePb.data().e(2));
        // printf("msgid:%d, timesec:%d, batteryinfo[1]:%d, batteryinfo[479]:%d\n", testMessagePb.mutable_ipcfchanl_header()->mesg_id(),testMessagePb.mutable_ipcfchanl_header()->timestamp_sec(),
        // testMessagePb.main_battery_info_data[1], testMessagePb.main_battery_info_data[479]);

        int socketfd = socket(AF_UNIX, SOCK_DGRAM, 0);
        if (socketfd == -1) {
            perror("socket");
            exit(EXIT_FAILURE);
        }

        struct sockaddr_un server_addr, client_addr;
        memset(&server_addr, 0, sizeof(struct sockaddr_un));
        server_addr.sun_family = AF_UNIX;
        strncpy(server_addr.sun_path, SOCKET_PATH, sizeof(server_addr.sun_path) - 1);

        while(1) {
            int ret = sendto(socketfd, &struc_obj, sizeof(_Cdd_IpcfShm_Cdd_IpcfPbMsg_Data_Acquire_M2A), 0, \
                (struct sockaddr *)(&server_addr), sizeof(struct sockaddr_un));
            if(ret <= 0) {
                perror("error");
                printf("send error");
            }
            printf("send success ret:%d\n",ret);

            sleep(1);
        }

    //     PbConvertor::MemTree stru;
    //     if (PbConvertor::serializedPb2struct("_Cdd_IpcfShm_Cdd_IpcfPbMsg_Data_Acquire_M2A", pSerializedPb, serializedPbSize, stru))
    //     {
    //         _Cdd_IpcfShm_Cdd_IpcfPbMsg_Data_Acquire_M2A *pTestMessage = (_Cdd_IpcfShm_Cdd_IpcfPbMsg_Data_Acquire_M2A *)stru.pMem;
    //         // printf("b:%d, c:%d, d:%lf, e:%d\n", pTestMessage->data.b, pTestMessage->data.c, pTestMessage->data.d, pTestMessage->data.e[2]);
    //         printf("msgid:%d, timesec:%d, batteryinfo[1]:%d, batteryinfo[479]:%d\n", pTestMessage->IpcfChanl_Header.Mesg_ID,
    //             pTestMessage->IpcfChanl_Header.Timestamp_Sec, pTestMessage->Main_Battery_Info_Data.bytes[1], pTestMessage->Main_Battery_Info_Data.bytes[479]);
    //         stru.release();
    //     }
    //     delete [] pSerializedPb;
    // }
}

int main()
{
    // test_demo();
    test_VDU();

    return 0;
}

// int main()
// {
//     testNamespace::TestMessage testMessage;
//     double arr1[3] = {1.234, 5.678, 9.101112};
//     testMessage.repeatedDoubleField = arr1;
//     testMessage.repeatedStringLengthField = 3;
//     char *arr2[3] = {"abc", "def", "ghi"};
//     testMessage.repeatedStringField = arr2;
//     testMessage.repeatedTestChildMessageLengthField = 3;
//     testNamespace::TestChildMessage arr3[3];
//     arr3[0] = testChildMessage;
//     arr3[1] = testChildMessage;
//     arr3[2] = testChildMessage;
//     testMessage.repeatedTestChildMessageField = arr3;

//     char *pSerializedPb;
//     size_t serializedPbSize;
//     if (PbConvertor::struct2serializedPb((const char *)&testMessage, "testPackage.TestMessage", pSerializedPb, serializedPbSize))
//     {
//         testPackage::TestMessage testMessagePb;
//         bool bRet = testMessagePb.ParseFromArray(pSerializedPb, serializedPbSize);

//         std::fstream ofs("test.pb.txt", std::ios::out | std::ios::trunc);
        
//         if(ofs.is_open()) {
//             testMessagePb.SerializeToOstream(&ofs);
//         }
//         ofs.close();
//         printf("stringField:%s, uint32Field:%d, repeatedStringField:%s\n", testMessagePb.stringfield().c_str(), testMessagePb.uint32field(), testMessagePb.repeatedstringfield(0).c_str());

//         PbConvertor::MemTree stru;
//         if (PbConvertor::serializedPb2struct("testPackage.TestMessage", pSerializedPb, serializedPbSize, stru))
//         {
//             testNamespace::TestMessage *pTestMessage = (testNamespace::TestMessage *)stru.pMem;
//             printf("stringField:%s, uint32Field:%d, repeatedStringField:%s\n", pTestMessage->stringField, pTestMessage->uint32Field, pTestMessage->repeatedStringField[0]);
//             stru.release();
//         }
//         delete [] pSerializedPb;
//     }

//     return 0;
// }
